include('Scripts/jsUnitCore.js');

function endsWith(string, str) {
	return string.substring(string.length - str.length) == str;
}

function startsWith(string, str) {
	return string.substring(0, str.length) == str;
}

function $A(nodes) {
	var n = [];
	for (i = 0; i < nodes.length; i++) {
		n.push(nodes.item(i));
	}
	return n;
}

function print_r( array, return_val ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Michael White (http://crestidg.com)
    // +   improved by: Ben Bryan
    // *     example 1: print_r(1, true);
    // *     returns 1: 1
 
    var output = "", pad_char = " ", pad_val = 4;
 
    var formatArray = function (obj, cur_depth, pad_val, pad_char) {
        if (cur_depth > 0) {
            cur_depth++;
        }
 
        var base_pad = repeat_char(pad_val*cur_depth, pad_char);
        var thick_pad = repeat_char(pad_val*(cur_depth+1), pad_char);
        var str = "";
 
        if (obj instanceof Array || obj instanceof Object) {
            str += "Array\n" + base_pad + "(\n";
            for (var key in obj) {
                if (obj[key] instanceof Array || obj[key] instanceof Object) {
                    str += thick_pad + "["+key+"] => "+formatArray(obj[key], cur_depth+1, pad_val, pad_char);
                } else {
                    str += thick_pad + "["+key+"] => " + obj[key] + "\n";
                }
            }
            str += base_pad + ")\n";
        } else {
            str = obj.toString();
        }
 
        return str;
    };
 
    var repeat_char = function (len, pad_char) {
        var str = "";
        for(var i=0; i < len; i++) { 
            str += pad_char; 
        };
        return str;
    };
    output = formatArray(array, 0, pad_val, pad_char);
 
    return output;
}

document.getElementById('main').onDragDrop = function (event) {
	if (event.dataType == "filenames" 
		&& event.items.length == 1
		&& endsWith(event.items[0], '.xml')) 
	{
		var testsXmlFilePath = event.items[0];
		var xmlPath = testsXmlFilePath.substring(0, testsXmlFilePath.lastIndexOf("/"));
		try {
			var tests = XMLDOM.parse(filesystem.readFile(testsXmlFilePath));
			
			// eval any scripts 
			var scripts = $A(tests.evaluate('/TestFixtures/Script'));
			scripts.forEach(function (scriptNode) {
				var scriptPath = scriptNode.getAttribute('path');
				include(xmlPath + "/" + scriptPath);
			});
			
			var result = {};
			
			// each test fixture
			var testfixtures = $A(tests.evaluate('/TestFixtures/TestFixture'));
			testfixtures.forEach(function (testFixtureNode) {
				var fixtureName = testFixtureNode.getAttribute('name');
				var setupFunction = testFixtureNode.getAttribute('setup');
				var teardownFunction = testFixtureNode.getAttribute('teardown');
				result[fixtureName] = {};
				if (Tests[fixtureName]) {
					var fixture = Tests[fixtureName];
					var tests = [];
					for (prop in fixture.prototype) {
						if (startsWith(prop, 'test')) {
							tests.push(prop);
						}
					}
					
					var i;
					for (i = 0; i < tests.length; i++) {
						var test = tests[i];
						log('running test:' + test);
						
						var r = '?';
						try {
							var testObject = new fixture();
							if (testObject.setup) {
								testObject.setup();
							}
							testObject[test]();
							r = 'P';
						} catch (e) {
							print (test + ":");
							if (e.isJsUnitException) {
								print (" failed:" + e.jsUnitMessage);
								r = 'F';
							} else if (e.description){
								print (" error: " + e.description);
								r = 'E';
							} else {
								print (" unknown exception thrown: " + e);
								r = 'E';
							}
						} finally {
							try {
								if (testObject.teardown) {
									testObject.teardown();
								}
							} catch (e) {
								// do nothing...
							}
						}
						result[fixtureName][test] = r;
					};
				}
			});
			
			var rslt = true;
			for (fixture in result) {
				if (!result)
					break;
				
				for (test in result[fixture]) {
					if (result[fixture][test] == 'E' || result[fixture][test] == 'F') {
						log(fixture + "." + test + ': ' + result[fixture][test]);
						rslt = false;
						break;
					}
				}
			}
			
			document.getElementById('indicator').style.backgroundColor = rslt ? 'green' : 'red';
		} catch (e) {
			alert (e);
		}
	} else {
		alert('not a xml');
	}
};
